/*
 This source file is part of the Swift.org open source project

 Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
 Licensed under Apache License v2.0 with Runtime Library Exception

 See http://swift.org/LICENSE.txt for license information
 See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

import TSCBasic
import TSCUtility

import SPMBuildCore
import Build
import PackageGraph
import PackageModel
import SourceControl
import Workspace

/// A wrapper for swift-symbolgraph-extract tool.
public struct SymbolGraphExtract {
    let tool: AbsolutePath

    init(tool: AbsolutePath) {
        self.tool = tool
    }

    public func dumpSymbolGraph(
        buildPlan: BuildPlan
    ) throws {
        let buildParameters = buildPlan.buildParameters
        let symbolGraphDirectory = buildPlan.buildParameters.symbolGraph
        try localFileSystem.createDirectory(symbolGraphDirectory, recursive: true)

        // Run the tool for each target in the root package.
        let targets = buildPlan.graph.rootPackages.flatMap{ $0.targets }.filter{ $0.type == .library || $0.type == .executable }
        for target in targets {
            var args = [String]()
            args += ["-module-name", target.c99name]
            args += buildParameters.targetTripleArgs(for: target)

            // FIXME: We should rename this to common Swift tools args or something.
            args += buildPlan.createAPIDigesterArgs()
            args += ["-module-cache-path", buildParameters.moduleCache.pathString]

            args += ["-output-dir", symbolGraphDirectory.pathString]

            print("-- Emitting symbol graph for", target.name)
            try runTool(args)
        }
        print("Files written to", symbolGraphDirectory.pathString)
    }

    func runTool(_ args: [String]) throws {
        let arguments = [tool.pathString] + args
        let process = Process(
            arguments: arguments,
            outputRedirection: .none,
            verbose: verbosity != .concise
        )
        try process.launch()
        try process.waitUntilExit()
    }
}

extension BuildParameters {
    /// The directory containing artifacts generated by the symbolgraph-extract tool.
    var symbolGraph: AbsolutePath {
        dataPath.appending(component: "symbolgraph")
    }
}
